﻿using System;

namespace Aeon.Emulator.Instructions.FPU
{
    internal static class Fadd
    {
        [Opcode("D8/0 mf32", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST032(VirtualMachine vm, float value)
        {
            AddToST064(vm, value);
        }

        [Opcode("D8C0+ st|DCC0 st0|DC/0 mf64", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST064(VirtualMachine vm, double value)
        {
            vm.Processor.FPU.ST0 += value;
        }

        [Opcode("DCC1", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST1(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(1);
            vm.Processor.FPU.SetRegisterValue(1, value + vm.Processor.FPU.ST0);
        }

        [Opcode("DCC2", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST2(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(2);
            vm.Processor.FPU.SetRegisterValue(2, value + vm.Processor.FPU.ST0);
        }

        [Opcode("DCC3", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST3(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(3);
            vm.Processor.FPU.SetRegisterValue(3, value + vm.Processor.FPU.ST0);
        }

        [Opcode("DCC4", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST4(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(4);
            vm.Processor.FPU.SetRegisterValue(4, value + vm.Processor.FPU.ST0);
        }

        [Opcode("DCC5", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST5(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(5);
            vm.Processor.FPU.SetRegisterValue(5, value + vm.Processor.FPU.ST0);
        }

        [Opcode("DCC6", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST6(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(6);
            vm.Processor.FPU.SetRegisterValue(6, value + vm.Processor.FPU.ST0);
        }

        [Opcode("DCC7", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST7(VirtualMachine vm)
        {
            double value = vm.Processor.FPU.GetRegisterValue(7);
            vm.Processor.FPU.SetRegisterValue(7, value + vm.Processor.FPU.ST0);
        }
    }

    internal static class Faddp
    {
        [Opcode("DEC0", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST0(VirtualMachine vm)
        {
            throw new InvalidOperationException();
        }

        [Opcode("DEC1", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST1(VirtualMachine vm)
        {
            Fadd.AddToST1(vm);
            vm.Processor.FPU.Pop();
        }

        [Opcode("DEC2", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST2(VirtualMachine vm)
        {
            Fadd.AddToST2(vm);
            vm.Processor.FPU.Pop();
        }

        [Opcode("DEC3", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST3(VirtualMachine vm)
        {
            Fadd.AddToST3(vm);
            vm.Processor.FPU.Pop();
        }

        [Opcode("DEC4", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST4(VirtualMachine vm)
        {
            Fadd.AddToST4(vm);
            vm.Processor.FPU.Pop();
        }

        [Opcode("DEC5", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST5(VirtualMachine vm)
        {
            Fadd.AddToST5(vm);
            vm.Processor.FPU.Pop();
        }

        [Opcode("DEC6", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST6(VirtualMachine vm)
        {
            Fadd.AddToST6(vm);
            vm.Processor.FPU.Pop();
        }

        [Opcode("DEC7", OperandSize = 16 | 32, AddressSize = 16 | 32)]
        public static void AddToST7(VirtualMachine vm)
        {
            Fadd.AddToST7(vm);
            vm.Processor.FPU.Pop();
        }
    }
}
